package fr.univnantes.lina.ftbcleaner;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import fr.univnantes.lina.ftbcleaner.FRBPropertiesWordFormCounter;
import fr.univnantes.lina.ftbcleaner.MultiWordDesambiguationCase;
import fr.univnantes.lina.ftbcleaner.WordLemma;

public class Desambiguate extends FRBPropertiesWordFormCounter {

	public Desambiguate() {
		super();
	}



	/**
	 * Depending on the desambiguation case, desambiguate catints
	 */
	public void desambiguateMultiWords (NodeList nodeList, Map<String,WordLemma> multiWordsExpressionHashMap) {

		//	int distinctLemma = 0;

		Set<String> numberOfMWLemmaWhichCanBeDesambiguated = new HashSet<String>();
		int numberOfMWOccurrenceWhichCanBeDesambiguated = 0;

		Set<String> numberOfMWLemmaWhichCannotBeDesambiguated = new HashSet<String>();
		int numberOfMWOccurrenceWhichCannotBeDesambiguated = 0;

		Set<String> numberOfMWLemmaWhichDoNotNeedToBeDesambiguated = new HashSet<String>();
		int numberOfMWOccurrenceWhichDoNotNeedToBeDesambiguated = 0;

		// for each mw occurrences 
		for(int i=0; (i < nodeList.getLength()); i++) {
			if (nodeList.item(i) instanceof Element) {
				Element aMWElement = (Element) nodeList.item(i);

				// Compute MW characteristics
				String lemma = aMWElement.getAttribute("lemma");

				// multiWordsExpressionHashMap must contain the lemma
				// since it has been built by the same index
				if (multiWordsExpressionHashMap.containsKey(lemma)) {

					// current MWE object corresponding to the lemma
					WordLemma aMWEObject = multiWordsExpressionHashMap.get(lemma);

					// the current mwe requires a desambiguation
					// TODO Should process all the multi words not only whose with a catint issue
					if (aMWEObject.getNumberOfNullCatintValue() >0)  {

						// (1) si MWWithACorrespondingSWSequence 
						// 	   alors associe à toutes les formes les bonnes features et si il n y a pas de correspondance exacte associe quand même avec la 1ère ayant le même nombre de mots
						// (2) sinon si MWWiOnlyOneCatintsWhichCoversTheWholeMW or MWWiMultipleCatintsButIdenticalWhichCoversTheWholeMW
						// 			 alors utilise cela pour définir les cat et utilise FB pour subcat, lemma, et mph des autres features
						// (3) 		 sinon	si  MWWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientWhichCoversTheWholeMW or 
						// 					alors utilise cela pour définir les cat et utilise FB pour subcat, lemma, et mph des autres features
						// (4)				sinon	si MWWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientButWiOneCoveringtheWhole or MWWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWiOneCoveringtheWhole
						// 							alors utilise cela pour définir les cat et utilise FB pour subcat, lemma, et mph des autres features
						int desambiguationCase = aMWEObject.getDesambiguisationCase();

						Boolean desambiguate = false; 
						// (1) si MWWithACorrespondingSWSequence 
						// 	   alors associe à toutes les formes les bonnes features et si il n y a pas de correspondance exacte associe quand même avec la 1ère ayant le même nombre de mots
						if ((desambiguationCase ==  MultiWordDesambiguationCase.MWWithACorrespondingSWSequence)) { // (1) 
							numberOfMWLemmaWhichCanBeDesambiguated.add(lemma);
							numberOfMWOccurrenceWhichCanBeDesambiguated ++;
							desambiguate = true; 
						}
						else if ((desambiguationCase == MultiWordDesambiguationCase.MWWiOnlyOneCatintsWhichCoversTheWholeMW) // (2) 
								|| (desambiguationCase ==  MultiWordDesambiguationCase.MWWiMultipleCatintsButIdenticalWhichCoversTheWholeMW) 
								) {
							numberOfMWLemmaWhichCanBeDesambiguated.add(lemma);
							numberOfMWOccurrenceWhichCanBeDesambiguated ++;
							desambiguate = true; 

						} else if ( (desambiguationCase ==  MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientWhichCoversTheWholeMW) // (3)
								) {
							numberOfMWLemmaWhichCanBeDesambiguated.add(lemma);
							numberOfMWOccurrenceWhichCanBeDesambiguated ++;
							desambiguate = true; 
						} else if ((desambiguationCase ==  MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientButWiOneCoveringtheWhole) // (4)
								|| (desambiguationCase ==  MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWiOneCoveringtheWhole) 
								) {
							numberOfMWLemmaWhichCanBeDesambiguated.add(lemma);
							numberOfMWOccurrenceWhichCanBeDesambiguated ++;
							desambiguate = true; 
						} else if ((desambiguationCase ==  MultiWordDesambiguationCase.MWWiIndependentFeaturesComputedFromSW) // (5)
								) {
							numberOfMWLemmaWhichCanBeDesambiguated.add(lemma);
							numberOfMWOccurrenceWhichCanBeDesambiguated ++;
							desambiguate = true; 
						}
						else {
							// all the case we cannot desambiguate 
							//if ((desambiguationCase ==  MultiWordDesambiguationCase.MWWiOnlyOneCatintsButNotCoveringTheWholeMW) 
							//
							//	|| (desambiguationCase ==  MultiWordDesambiguationCase.MWWiMultipleCatintsButIdenticalButNotCoveringTheWholeMW) 
							//	|| (desambiguationCase ==  MultiWordDesambiguationCase.MWWoCatints) 
							//	|| (desambiguationCase ==  MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWoOneSufficientlyMoreSalientAndWoOneCoveringtheWhole) 
							//	|| (desambiguationCase ==  MultiWordDesambiguationCase.MWWiMultipleCatintsNotIdenticalWiOneSufficientlyMoreSalientNotCoveringTheWholeMWButWoOneCoveringtheWhole) ) {
							//
							//}
							numberOfMWLemmaWhichCannotBeDesambiguated.add(lemma);
							numberOfMWOccurrenceWhichCannotBeDesambiguated++;

							// TODO work with single word features 
						}
						// do the desambiguation (modify the dom)

						/*
						//if (desambiguate) {
						String occWordForm = aMWElement.getTextContent().trim();

						Map<String,String> catintsMap = aMWEObject.getMostProbableCatintSequence();
						Map<String,String> subcatsMap = aMWEObject.getMostProbableSubcatSequence();
						Map<String,String> lemmasMap = aMWEObject.getMostProbableLemmaSequence();
						Map<String,String> mphsMap = aMWEObject.getMostProbableMphSequence();

						String catintsString = catintsMap.get(occWordForm);
						String subcatsString = subcatsMap.get(occWordForm);
						String lemmasString = lemmasMap.get(occWordForm);
						String mphsString = mphsMap.get(occWordForm);

						String catintsStringArray[] = null;
						String subcatsStringArray[] = null;
						String lemmasStringArray[] = null;
						String mphsStringArray[] = null;

						Boolean undefinedCatintCase = false;
						Boolean undefinedSubcatCase = false;
						Boolean undefinedLemmaCase = false;
						Boolean undefinedMphCase = false;

						if (catintsString != null) {catintsStringArray = catintsString.split(" ");				}
						else {	
							undefinedCatintCase = true; 
							//System.err.println("Debug: catintsString null, occWordForm >"+occWordForm+"<");		

						}
						if (subcatsString != null) {subcatsStringArray = subcatsString.split(" ");	}
						else {
							undefinedSubcatCase = true; 
							//System.err.println("Debug: subcatsString null, occWordForm >"+occWordForm+"<");					
						}
						if (lemmasString != null) {	lemmasStringArray = lemmasString.split(" ");															}
						else {	
							undefinedLemmaCase = true; 	
							//System.err.println("Debug: lemmasString null occWordForm >"+occWordForm+"<");						
						}
						if (mphsString != null) { mphsStringArray = mphsString.split(" ");							}
						else {	
							undefinedMphCase = true; 							
							//System.err.println("Debug: mphsString null occWordForm >"+occWordForm+"<");							
						}

						NodeList partOfMultiWordsnodeList = aMWElement.getChildNodes();

						// 
						if (undefinedCatintCase && undefinedSubcatCase && undefinedLemmaCase && undefinedMphCase) {

							for(int j=0; (j < partOfMultiWordsnodeList.getLength()); j++) {
								if (partOfMultiWordsnodeList.item(j) instanceof Element) {
									Element aPOMWE = (Element) partOfMultiWordsnodeList.item(j);

									NodeList fils = aPOMWE.getChildNodes();
									// Si empty element
									// we do not modify amalgame part of word
									if (fils.getLength() != 0) {
										// TODO we overwrite existing catint value... which may be bad
										// we could use it to desambiguate...
										String catVal = "U";
										String subcatVal  = "U";
										String lemmaVal  = "U";
										String mphVal = "U";

										aPOMWE.setAttribute("catint", catVal);
										aPOMWE.setAttribute("subcat", subcatVal);
										aPOMWE.setAttribute("lemma", lemmaVal);
										aPOMWE.setAttribute("mph", mphVal);
									}
								}
							}
						}
						else	
							// can hold since catintsStringArray does not consider amalgame and partOfMultiWordsnodeList does
							//if (catintsStringArray.length == partOfMultiWordsnodeList.getLength() || undefinedCatintCase|| undefinedSubcatCase|| undefinedLemmaCase|| undefinedMphCase) {
						{
							// for each word partof mw 
							int s =0;
							int t = 0;
							while (t < partOfMultiWordsnodeList.getLength()) {
								if (partOfMultiWordsnodeList.item(t) instanceof Element) {
									Element aPOMWE = (Element) partOfMultiWordsnodeList.item(t);

									NodeList fils = aPOMWE.getChildNodes();
									// Si empty element
									// in order to handle the amalgame word part of multi word
									if (fils.getLength() != 0) {
										s++;
									}


									// TODO we overwrite existing catint value... which may be bad
									// we could use it to desambiguate...
									String catVal = "U";
									String subcatVal  = "U";
									String lemmaVal  = "U";
									String mphVal = "U";

									//System.err.println("Debug: occWordForm "+occWordForm+" s "+ s);

									//System.err.println("Debug: catintsStringArray[s] "+ catintsStringArray[s]);
									if (!undefinedCatintCase) catVal =  catintsStringArray[s];
									if (!undefinedSubcatCase) subcatVal =  subcatsStringArray[s];
									if (!undefinedLemmaCase) lemmaVal =  lemmasStringArray[s];
									if (!undefinedMphCase) mphVal =  mphsStringArray[s];

									aPOMWE.setAttribute("catint", catVal);
									aPOMWE.setAttribute("subcat", subcatVal);
									aPOMWE.setAttribute("lemma", lemmaVal);
									aPOMWE.setAttribute("mph", mphVal);

								}
								t++	;
								//else {
								//	System.err.println("Debug: partOfMultiWordsnodeList.item(j) is not instanceof Element");
								//}

							}

							//}
							//else {
							//	System.err.println("Warning: this multi word lemma have at least two distinct forms with different size ("+lemma+" occurs here as "+occWordForm+")");
							//}
						}
						//
						//aMWEObject.display();
*/
						//}
					}
					else {
						// which do not need 
						numberOfMWOccurrenceWhichDoNotNeedToBeDesambiguated++;
						numberOfMWLemmaWhichDoNotNeedToBeDesambiguated.add(lemma);
						//numberOfMWOccurrenceWhichDoNotNeedToBeDesambiguated += aMWEObject.getOccurrence();
					}
				}
				else {
					System.err.println("Error: a aap's key is missing from an index which previously was used to build the map");
				}
			}
		}

		System.err.println("Info: # of multi-words which do not need to be desambiguated ; lemma = "+numberOfMWLemmaWhichDoNotNeedToBeDesambiguated.size()
				+ ", occurrences = "+numberOfMWOccurrenceWhichDoNotNeedToBeDesambiguated);
		//System.err.println("Info: # of multi-words occurrences which do not need to be desambiguated = "+ 
		//		numberOfMWOccurrenceWhichDoNotNeedToBeDesambiguated);
		System.err.println("Info: # of multi-words we can desambiguate lemma  = "+ numberOfMWLemmaWhichCanBeDesambiguated.size()
				+ ", occurrences = "+numberOfMWOccurrenceWhichCanBeDesambiguated);
		//System.err.println("Info: # of multi-words lemma we cannot desambiguate = "+ 
		//		numberOfMWOccurrenceWhichCanBeDesambiguated);
		System.err.println("Info: # of multi-words we do not manage to desambiguate lemma = "+ 
				numberOfMWLemmaWhichCannotBeDesambiguated.size()+ ", occurrences = "+numberOfMWOccurrenceWhichCannotBeDesambiguated);
		//System.err.println("Info: # of multi-words occurrences we cannot desambiguate = "+ 
		//		numberOfMWOccurrenceWhichCannotBeDesambiguated);
	}

}